
package me.zhengjie.rest;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import me.zhengjie.base.AjaxResult;
import me.zhengjie.domain.AppWork;
import me.zhengjie.domain.AppWorkCoverPoint;
import me.zhengjie.domain.AppWorkGps;
import me.zhengjie.modules.system.domain.DictDetail;
import me.zhengjie.modules.system.service.DictDetailService;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.rest.vo.GpsJsonVO;
import me.zhengjie.rest.vo.GpsVO;
import me.zhengjie.rest.vo.OperationVO;
import me.zhengjie.service.*;
import me.zhengjie.service.dto.*;
import me.zhengjie.utils.DateUtils;
import me.zhengjie.utils.GPSMath;
import me.zhengjie.utils.SecurityUtils;
import me.zhengjie.utils.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.sql.Timestamp;
import java.util.*;

/**
* @website https://el-admin.vip
* @author IQW
* @date 2022-07-03
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "巡护任务管理")
@RequestMapping("/api/work")
public class ApiWorkController {

    private final AppWorkService appWorkService;
    private final UserService appUserService;
    private final AppWorkGpsService appWorkGpsService;
    private final AppEventService appEventService;
    private final AppWorkCoverService appWorkCoverService;
    private final AppWorkCoverPointService appWorkCoverPointService;
    private final DictDetailService dictDetailService;

    @GetMapping(value = "/list")
    @ApiOperation("巡护列表(未完成，未过期)")
    public AjaxResult queryAppWork(AppWorkQueryCriteria criteria,
                                   @PageableDefault(sort = {"workId"}, direction = Sort.Direction.DESC) Pageable pageable){

        criteria.setUserId(SecurityUtils.getCurrentUserId().intValue());
        criteria.setStatusLessTh(1);
        return AjaxResult.success(appWorkService.queryAllApi(criteria,pageable));
    }

    @GetMapping(value = "/log")
    @ApiOperation("巡护日志列表（已完成）")
    public AjaxResult queryAppWorkLog(@RequestParam(defaultValue = "") String startTime,
                                      @RequestParam(defaultValue = "") String endTime,
                                      AppWorkQueryCriteria criteria,
                                      @PageableDefault(sort = {"workId"}, direction = Sort.Direction.DESC) Pageable pageable){

        criteria.setStatus(2);
        criteria.setUserId(SecurityUtils.getCurrentUserId().intValue());
        if(!StringUtils.isEmpty(startTime) && !StringUtils.isEmpty(endTime)){
            List<Timestamp> date = new LinkedList<>();
            date.add(DateUtils.parseTimestamp(startTime));
            date.add(DateUtils.parseTimestamp(endTime+" 23:59:59"));
            criteria.setStartTimes(date);
        }
        return AjaxResult.success(appWorkService.queryAllApi(criteria,pageable));
    }

    @PostMapping(value = "/operation")
    @ApiOperation("巡护操作")
    public AjaxResult operations(@Validated @RequestBody OperationVO operationVO){

        Integer userId = SecurityUtils.getCurrentUserId().intValue();
        UserDto user = appUserService.findById(userId);

        if(StringUtils.isNull(operationVO.getWorkId())||StringUtils.isNull(operationVO.getType())){
            return AjaxResult.error("参数错误");
        }

        if(operationVO.getType() == 1) {
            //检测当前用户是否有未关闭的任务
            Integer check = appWorkService.selectWorking(userId);
            if(check >0 && !check.equals(operationVO.getWorkId())){
                return AjaxResult.error(-110,"请先完成之前的巡护任务");
            }
        }
        if(operationVO.getType() == 2){
            if(StringUtils.isEmpty(operationVO.getNote()) && StringUtils.isEmpty(operationVO.getImgs()) && StringUtils.isEmpty(operationVO.getVoice())){
                return AjaxResult.error("内容不能为空");
            }
            if(StringUtils.isEmpty(operationVO.getAddress()) || StringUtils.isNull(operationVO.getLat()) || StringUtils.isNull(operationVO.getLon())){
                return AjaxResult.error("GPS参数错误");
            }
            if(operationVO.getLat() < 0.01 || operationVO.getLon() < 0.01  ){
                return AjaxResult.error("未获取到经纬度信息，请重试");
            }
        }
        AppWork appWork = appWorkService.findOne(operationVO.getWorkId());
        if(null == appWork){
            return AjaxResult.error("巡护任务不存在");
        }
        if(null != appWork.getUserId() && userId != appWork.getUserId().intValue()){
            return AjaxResult.error("用户身份不匹配");
        }

        if(appWork.getStatus() == 2){
            return AjaxResult.error("抱歉，任务已经结束");
        }
        if(appWork.getStatus() == 3){
            return AjaxResult.error("抱歉，任务已过期");
        }

        if(operationVO.getType() == 1){
            //更新状态为开始
            if(appWork.getStatus() == 0){
                appWorkService.updateStatus(appWork.getWorkId(), 1,false);
            }
        }else if(operationVO.getType() == 2){

            if(appWork.getStatus() == 0){
                return AjaxResult.error("抱歉，任务还未开始");
            }
            //检测是否在范围内（优先读取任务的，再读取用户的经纬度）
            double[] start = null;
            if(StringUtils.isNull(appWork.getLon()) || StringUtils.isNull(appWork.getLat())){
                start = new double[]{user.getLon(),user.getLat()};
            }else{
                if(StringUtils.isNull(user.getLon()) || StringUtils.isNull(user.getLat())){
                    return AjaxResult.error("抱歉，任务未配置终点经纬度");
                }
                start = new double[]{appWork.getLon(),appWork.getLat()};
            }
            System.out.println("--------上送经纬度app-------");
            System.out.println(operationVO.getLon());
            System.out.println(operationVO.getLat());
            System.out.println(operationVO.getAddress());

            double gpsMails = GPSMath.getMeter(start,new double[]{operationVO.getLon(),operationVO.getLat()});
            Integer mailsSet = 200;    //米 默认距离
            List<DictDetail> miSet = dictDetailService.queryAllBydictId(23L);
            if(null != miSet && miSet.size()>0){
                try {
                    mailsSet = Integer.valueOf(miSet.get(0).getValue());
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println("---------无法转换整数-------------");
                }
            }
            System.out.println("计算距离："+gpsMails+"，后台设置距离："+mailsSet);
            if(gpsMails > mailsSet){
                return AjaxResult.error("抱歉，不在巡护终点范围内");
            }

            //更新数据及状态
            appWork.setStatus(2);
            appWork.setEndTime(DateUtils.getNowTimestamp());

            appWork.setNote(operationVO.getNote());
            appWork.setImgs(operationVO.getImgs());
            appWork.setVoice(operationVO.getVoice());
            appWork.setVtime(operationVO.getVtime());

            appWorkService.update(appWork);

        }else {
            //终止巡护，更新状态并删除事件和GPS
            appWorkService.updateStatus(appWork.getWorkId(), 0,true);
            appWorkGpsService.deleteByWorkId(appWork.getWorkId());
            appEventService.deleteByWorkId(appWork.getWorkId());
        }

        return  AjaxResult.success("操作成功",String.valueOf(operationVO.getType()));
    }


    @PostMapping(value = "/gpsUp")
    @ApiOperation("GPS上传")
    public AjaxResult gpsUp(@Validated @RequestBody GpsVO gpsVO){

        if(StringUtils.isNull(gpsVO.getWorkId())||StringUtils.isNull(gpsVO.getWorkMile())||StringUtils.isEmpty(gpsVO.getGps())){
            return AjaxResult.error("参数错误");
        }

        AppWork appWork = appWorkService.findOne(gpsVO.getWorkId());
        if(null == appWork){
            return AjaxResult.error("巡护任务不存在");
        }
//        if(appWork.getStatus() == 2){
//            return AjaxResult.error("抱歉，任务已经结束");
//        }
        try {
            JSONArray arr = JSONObject.parseArray(gpsVO.getGps());
            for(int i=0;i<arr.size();i++){
                AppWorkGps gps = new AppWorkGps();
                gps.setTime(arr.getJSONObject(i).getLongValue("time"));
                gps.setLat(arr.getJSONObject(i).getDoubleValue("lat"));
                gps.setLon(arr.getJSONObject(i).getDoubleValue("lon"));

                gps.setWorkId(gpsVO.getWorkId());
                gps.setWorkMile(gpsVO.getWorkMile());
                gps.setWorkTime(0);
                gps.setStatus(1);
                appWorkGpsService.create(gps);
            }
            //更新，叠加当前小计距离
            if(null == appWork.getWorkMile() ){
                appWork.setWorkMile(0f);
            }
            appWork.setWorkMile(appWork.getWorkMile()+ gpsVO.getWorkMile());
            appWorkService.update(appWork);

        }catch (Exception e){
            e.printStackTrace();
            return  AjaxResult.error("JSON解析失败："+e.getMessage());
        }

        return  AjaxResult.success("操作成功");
    }

    @GetMapping(value = "/detail")
    @ApiOperation("巡护详情")
    public AjaxResult detail(@RequestParam Integer workId){

        AppWorkDto appWork = appWorkService.findById(workId);
        if(null == appWork){
            return AjaxResult.error("巡护任务不存在");
        }

        UserDto user1 = appUserService.findById(appWork.getUserId());
        if(null == user1){
            return AjaxResult.error("关联用户数据不存在");
        }

        Map<String, Object> ret = new HashMap<>();
        ret.put("status",appWork.getStatus());
        ret.put("lon",appWork.getLon());
        ret.put("lat",appWork.getLat());
        ret.put("address",appWork.getAddress());
        ret.put("note",appWork.getNote());
        ret.put("imgs",appWork.getImgs());
        ret.put("voice",appWork.getVoice());
        ret.put("nickName",user1.getNickName());
        ret.put("workNo",user1.getWorkNo());
        ret.put("workTime",appWork.getWorkTime());
        ret.put("workMile",appWork.getWorkMile());

        AppWorkCoverQueryCriteria criteria = new AppWorkCoverQueryCriteria();
        criteria.setStatus(1);

        AppWorkCoverPointQueryCriteria criteriaPoint = new AppWorkCoverPointQueryCriteria();
        criteriaPoint.setAreaId(user1.getAreaId());

        List<AppWorkCoverDto> appWorkCoverList = appWorkCoverService.queryAll(criteria);
        List<AppWorkCover2Dto> appWorkCoverList2 = new LinkedList<>();

        for(AppWorkCoverDto item:appWorkCoverList){
            AppWorkCover2Dto tmp = new AppWorkCover2Dto();
            tmp.setId(item.getId());
            tmp.setTitle(item.getTitle());
            tmp.setImg(item.getImg());
            tmp.setImg2(item.getImg2());
            tmp.setImg3(item.getImg3());
//            tmp.setGps(item.getGps());

            criteriaPoint.setCateId(item.getId());
            List<AppWorkCoverPointDto> list = appWorkCoverPointService.queryAll(criteriaPoint);
            List<GpsJsonVO> gpsList = new LinkedList<>();
            for (AppWorkCoverPointDto item2 : list){
                GpsJsonVO json = new GpsJsonVO();
                json.setLat(item2.getLat());
                json.setLon(item2.getLon());
                gpsList.add(json);
            }
            //map转json字符串
            if(gpsList.size()>0) {
                String jsonStr = JSON.toJSONString(gpsList);
                tmp.setGps(jsonStr);
            }

            appWorkCoverList2.add(tmp);

        }
        ret.put("list1",appWorkCoverList2);

        //已完成轨迹
        if(appWork.getStatus() == 2) {
            AppWorkGpsQueryCriteria criteria2 = new AppWorkGpsQueryCriteria();
            criteria2.setWorkId(workId);
            List<AppWorkGpsDto> appWorkGpsList = appWorkGpsService.queryAll(criteria2);
            if (null != appWorkGpsList) {
                List<AppWorkGps2Dto> appWorkGpsList2 = new LinkedList<>();

                for (AppWorkGpsDto item : appWorkGpsList) {
                    AppWorkGps2Dto tmp = new AppWorkGps2Dto();
                    tmp.setTime(item.getTime());
                    tmp.setLon(item.getLon());
                    tmp.setLat(item.getLat());
                    appWorkGpsList2.add(tmp);
                }

                ret.put("list2", appWorkGpsList2);
            }
        }
        return AjaxResult.success(ret);
    }

    @GetMapping(value = "/detailLog")
    @ApiOperation("巡护日志详情")
    public AjaxResult detailLog(@RequestParam Integer workId){

        AppWorkDto appWork = appWorkService.findById(workId);
        if(null == appWork){
            return AjaxResult.error("巡护任务不存在");
        }
        UserDto user1 = appUserService.findById(appWork.getUserId());
        if(null == user1){
            return AjaxResult.error("关联用户数据不存在");
        }

        Map<String, Object> ret = new HashMap<>();
        ret.put("status",appWork.getStatus());
        ret.put("lon",appWork.getLon());
        ret.put("lat",appWork.getLat());
        ret.put("address",appWork.getAddress());
        ret.put("endTime",appWork.getEndTime());
        ret.put("note",appWork.getNote());
        ret.put("imgs",appWork.getImgs());
        ret.put("voice",appWork.getVoice());
        ret.put("nickName",user1.getNickName());
        ret.put("workNo",user1.getWorkNo());
        ret.put("workTime",appWork.getWorkTime());
        ret.put("workMile",appWork.getWorkMile());

        if(appWork.getStatus() == 2) {
            AppWorkGpsQueryCriteria criteria2 = new AppWorkGpsQueryCriteria();
            criteria2.setWorkId(workId);
            List<AppWorkGpsDto> appWorkGpsList = appWorkGpsService.queryAll(criteria2);
            if (null != appWorkGpsList) {
                List<AppWorkGps2Dto> appWorkGpsList2 = new LinkedList<>();

                for (AppWorkGpsDto item : appWorkGpsList) {
                    AppWorkGps2Dto tmp = new AppWorkGps2Dto();
                    tmp.setTime(item.getTime());
                    tmp.setLon(item.getLon());
                    tmp.setLat(item.getLat());
                    appWorkGpsList2.add(tmp);
                }

                ret.put("list", appWorkGpsList2);
            }
        }
        return AjaxResult.success(ret);
    }


}